package org.internna.ossmoney.model.qif;

import java.util.Date;
import java.text.SimpleDateFormat;
import org.internna.ossmoney.util.DateUtils;

public final class Register implements Comparable<Register> {

	private static final SimpleDateFormat dFormat = new SimpleDateFormat("yyyy-mm-dd");

	public enum AccountType {

		BANK("account.type.bank"), CCARD("account.type.creditcard"), INVST("account.type.investment");

		private String dbType;

		private AccountType(String type) {
			this.dbType = type;
		}

		@Override public String toString() {
			return dbType;
		}

	}

	public enum Operation {

		BUY, DEPOSIT_OR_WITHDRAWAL, INTEREST_INCREASE, OPEN_BALANCE, SELL, TRANSFER;

		public static Operation fromValue(String value) {
			Operation operation = INTEREST_INCREASE;
			if (value != null) {
				if ("buy".equalsIgnoreCase(value)) {
					operation = BUY;
				} else if ("sell".equalsIgnoreCase(value)) {
					operation = SELL;
				}
			}
			return operation;
		}

	}

	private Date date;
	private String payee;
	private AccountType type;
	private String investment;
	private String description;
	private String targetAccount;
	private Double quantity, price;
	private String category, subcategory;
	private Boolean skipped = Boolean.FALSE;
	private Boolean reconciled = Boolean.FALSE;
	private Double amount = Double.NEGATIVE_INFINITY;
	private Operation operation = Operation.DEPOSIT_OR_WITHDRAWAL;

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = DateUtils.getRandomTimeDate(date);
	}

	public String getPayee() {
		return payee;
	}

	public void setPayee(String payee) {
		this.payee = payee;
	}

	public Double getAmount() {
		return amount;
	}

	public void setAmount(Double amount) {
		this.amount = amount;
	}

	public AccountType getType() {
		return type;
	}

	public void setType(AccountType type) {
		this.type = type;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public Operation getOperation() {
		return operation;
	}

	public void setOperation(Operation operation) {
		this.operation = operation;
	}

	public Double getQuantity() {
		return quantity;
	}

	public void setQuantity(Double quantity) {
		this.quantity = quantity;
	}

	public Double getPrice() {
		return price;
	}

	public void setPrice(Double price) {
		this.price = price;
	}

	public String getCategory() {
		return category;
	}

	public void setCategory(String category) {
		this.category = category;
	}

	public String getSubcategory() {
		return subcategory;
	}

	public void setSubcategory(String subcategory) {
		this.subcategory = subcategory;
	}

	public String getTargetAccount() {
		return targetAccount;
	}

	public void setTargetAccount(String targetAccount) {
		this.targetAccount = targetAccount;
	}

	public Boolean getReconciled() {
		return reconciled;
	}

	public void setReconciled(Boolean reconciled) {
		this.reconciled = reconciled;
	}

	public String getInvestment() {
		return investment;
	}

	public void setInvestment(String investment) {
		this.investment = investment;
	}

	public boolean isInvestment() {
		return operation != null && (operation.equals(Operation.BUY) | operation.equals(Operation.SELL) | operation.equals(Operation.INTEREST_INCREASE)); 
	}

	public Boolean isSkipped() {
		return skipped;
	}

	public void setSkipped(Boolean skipped) {
		this.skipped = skipped;
	}

	@Override public int compareTo(Register other) {
		return other == null
				? -1
				: this == other
					? 0
					: Operation.OPEN_BALANCE.equals(operation)
						? -1
						: Operation.OPEN_BALANCE.equals(other.operation)
							? 1
							: other.date == null
								? -1
								: date == null
									? 1
									: other.date == null
										? -1
										: date.compareTo(other.date);
	}

	@Override public String toString() {
		StringBuilder builder = new StringBuilder();
		if (operation != null) {
			builder.append(operation).append(" ");
		}
		if (date != null) {
			builder.append(dFormat.format(operation)).append(" ");
		}
		if (amount != null) {
			builder.append(amount).append(" ");
		}
		if (payee != null) {
			builder.append(payee).append(" ");
		}
		return builder.toString();
	}

}
